package com.translation.assistant.manager;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.huawei.agconnect.config.AGConnectServicesConfig;
import com.huawei.hmf.tasks.OnFailureListener;
import com.huawei.hmf.tasks.OnSuccessListener;
import com.huawei.hms.mlsdk.common.MLApplication;
import com.huawei.hms.mlsdk.model.download.MLLocalModelManager;
import com.huawei.hms.mlsdk.model.download.MLModelDownloadListener;
import com.huawei.hms.mlsdk.model.download.MLModelDownloadStrategy;
import com.huawei.hms.mlsdk.translate.MLTranslateLanguage;
import com.huawei.hms.mlsdk.translate.MLTranslatorFactory;
import com.huawei.hms.mlsdk.translate.local.MLLocalTranslateSetting;
import com.huawei.hms.mlsdk.translate.local.MLLocalTranslator;
import com.huawei.hms.mlsdk.translate.local.MLLocalTranslatorModel;
import com.translation.assistant.callback.OnModelListener;
import com.translation.assistant.callback.TranslateCallback;

import java.util.Set;

public class OfflineJavaTranslatorManager {
    private MLLocalTranslator mlLocalTranslator;
    private MLLocalModelManager manager;

    public OfflineJavaTranslatorManager(Context context) {
        manager = MLLocalModelManager.getInstance();
        setApiKey(context);
    }

    private void setApiKey(Context context) {
        MLApplication.getInstance().setApiKey(AGConnectServicesConfig.fromContext(context).getString("client/api_key"));
    }

    /**
     * 执行文本离线翻译
     */
    public void translate(String input, String originLang, String targetLang, TranslateCallback callback){
        if(TextUtils.isEmpty(input)){
            callback.onFailed(1001,"The translated text is empty");
            return;
        }
        Set<String> supportedLanguages = syncGetLocalAllLanguages();
        if(!supportedLanguages.contains(originLang)){
            callback.onFailed(1002,"Unsupported language:${originLang}");
            return;
        }
        if(!supportedLanguages.contains(targetLang)){
            callback.onFailed(1003,"Unsupported language:${targetLang}");
            return;
        }

        Log.d("AssistantManager", "创建离线翻译器");
        MLLocalTranslateSetting setting = new MLLocalTranslateSetting.Factory() // 设置源语言的编码，使用ISO 639-1标准。此设置为必选项，如果不设置，将可能出现问题。
                .setSourceLangCode(originLang) // 设置目标语言的编码，使用ISO 639-1标准。此设置为必选项，如果不设置，将可能出现问题。
                .setTargetLangCode(targetLang)
                .create();
        if(mlLocalTranslator != null) mlLocalTranslator.stop();
        mlLocalTranslator = MLTranslatorFactory.getInstance().getLocalTranslator(setting);
        Log.d("AssistantManager", "开始离线翻译");
        //异步方法
        long startTime = System.currentTimeMillis();
        mlLocalTranslator.asyncTranslate(input).addOnSuccessListener(new OnSuccessListener<String>() {
            @Override
            public void onSuccess(String s) {
                Log.i("AssistantManager", "离线翻译耗时:${System.currentTimeMillis() - startTime}ms");
                mlLocalTranslator.stop();
                mlLocalTranslator = null;
                callback.onCompleted(s, originLang, targetLang, true);
            }
        }).addOnFailureListener(new OnFailureListener() {

            @Override
            public void onFailure(Exception e) {
                Log.e("AssistantManager", "离线翻译失败: " + e.getMessage());
                mlLocalTranslator.stop();
                mlLocalTranslator = null;
                callback.onFailed(1004, e.getMessage());
            }
        });
    }

    /**
     * 异步方法获取本地离线翻译所支持的语种
     */
    public void getOfflineTranslatorLang(OnSuccessListener<Set<String>> successLanguage) {
        //异步方法
        MLTranslateLanguage.getLocalAllLanguages().addOnSuccessListener(successLanguage);
    }

    /**
     * 同步方法获取本地离线翻译所支持的语种
     */
    public Set<String>  syncGetLocalAllLanguages() {
        Set<String> supportedLanguages = MLTranslateLanguage.syncGetLocalAllLanguages();
        Log.d("AssistantManager", "同步方法获取本地离线翻译所支持的语种：${supportedLanguages}");
        return supportedLanguages;
    }

    /**
     * 下载语言包：sourceLangCode
     * 下载进度监听器：MLModelDownloadListener
     * 下载成功后回调：OnSuccessListener<Void>
     * 下载失败后回调：OnFailureListener
     */
    public void downloadModel(
            String sourceLangCode,
            OnModelListener<Void> listener
            ) {
        // 获取模型管理器。
        MLLocalTranslatorModel model = new MLLocalTranslatorModel.Factory(sourceLangCode).create();
        // 设置模型下载策略。
        MLModelDownloadStrategy downloadStrategy = new MLModelDownloadStrategy.Factory()
                .needWifi() // 推荐wifi环境下下载。
                .create();

        //下载进度监听器
        MLModelDownloadListener modelDownloadListener = new MLModelDownloadListener() {
            @Override
            public void onProcess(long alreadyDownLength, long totalLength) {
                listener.onProcess(alreadyDownLength, totalLength);
            }
        };
        // 下载模型。
        manager.downloadModel(model, downloadStrategy, modelDownloadListener)
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void s) {
                        listener.onSuccess(s);
                    }
                }).addOnFailureListener(new OnFailureListener() {

                    @Override
                    public void onFailure(Exception e) {
                        listener.onFailure(e);
                    }
                });

    }

    public void deleteModel(String languageCode, OnModelListener<Void> listener) {
        // 获取模型管理器。
        MLLocalTranslatorModel model = new MLLocalTranslatorModel.Factory(languageCode).create();
        manager.deleteModel(model).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void s) {
                listener.onSuccess(s);
            }
        }).addOnFailureListener(new OnFailureListener() {

            @Override
            public void onFailure(Exception e) {
                listener.onFailure(e);
            }
        });
    }
}
